#include <config.h>
#include <debug.h>
#include <header.h>
#include <rules.h>
#include <xml_util.h>

#include "gui.h"
#include "language.h"

#define CELL_ICON_SIZE  16
extern void del_process_cache_entry(const char * path);

static GtkListStore *list_store = NULL;
static GtkTreeSelection *selection = NULL;
enum
{
  ICON,
  NAME,
  PATH,
  ALLOW
};
static GtkListStore *get_list_store(void);
static GtkWidget *get_tree_view(GtkListStore *list_store);
static void cellrender_toggled(GtkCellRendererToggle *cell_renderer,
                               gchar *path,
                               gpointer user_data);
static void init_program_list_store(GtkListStore *list_store);
static void delete_item(GtkWidget *widget, gpointer data);
GtkWidget *get_app_page(void)
{
  GtkWidget *vbox = NULL;
  GtkWidget *hbox_top = NULL;
  GtkWidget *hbox_bottom = NULL;
  GtkWidget *scrolled_window = NULL;
  GtkWidget *scrolled_window_vbox = NULL;
  GtkWidget *del_button = NULL;
  GtkWidget *tree_view = NULL;
  vbox = gtk_vbox_new(FALSE, 0);
  hbox_top = gtk_hbox_new(FALSE, 0);
  hbox_bottom = gtk_hbox_new(TRUE, 0);
  gtk_box_pack_start(GTK_BOX(vbox), hbox_top, FALSE, FALSE, 5);
  gtk_box_pack_start(GTK_BOX(vbox), hbox_bottom, FALSE, FALSE, 10);
  gtk_container_border_width(GTK_CONTAINER(hbox_top), 0);
  gtk_container_border_width(GTK_CONTAINER(hbox_bottom), 0);
  scrolled_window = gtk_scrolled_window_new(NULL, NULL);
  gtk_container_border_width(GTK_CONTAINER(scrolled_window), 0);
  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),
                                 GTK_POLICY_AUTOMATIC,
                                 GTK_POLICY_AUTOMATIC);
  gtk_widget_set_usize(scrolled_window, SCROLLED_WINDOW_WIDTH,
                       SCROLLED_WINDOW_HEIGHT);
  gtk_box_pack_start(GTK_BOX(hbox_top), GTK_WIDGET(scrolled_window), TRUE, TRUE, 0);
  scrolled_window_vbox = gtk_vbox_new(FALSE, 0);
  gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled_window),
                                        scrolled_window_vbox);
  list_store = get_list_store();
  tree_view = get_tree_view(list_store);
  init_program_list_store(list_store);
  gtk_box_pack_start(GTK_BOX(scrolled_window_vbox), tree_view, TRUE, TRUE, 0);
  del_button = gtk_button_new_from_stock(GTK_STOCK_DELETE);
  gtk_box_pack_start(GTK_BOX(hbox_bottom), GTK_WIDGET(del_button), FALSE, FALSE, 0);
  /*connect signal*/
  gtk_signal_connect(GTK_OBJECT(del_button), "clicked", G_CALLBACK(delete_item), NULL);
  return vbox;
}

void add_general_list_store(char *path, int allow)
{
  GtkTreeIter iter;
  char *mark = NULL;

  GdkPixbuf *icon_pixbuf = NULL;
  GdkPixbuf *temp_icon_pixbuf = NULL;
  char icon_path[256] = {0};

  char md5sum_now[MD5SUM_LEN+1]={0};

  md_buffer((void *)path, strlen(path), md5sum_now);
  sprintf(icon_path, "%s/%s.png", APP_ICON_PATH, md5sum_now);

  temp_icon_pixbuf = gdk_pixbuf_new_from_file(icon_path, NULL);
  if (NULL == temp_icon_pixbuf)
  {
    temp_icon_pixbuf = gdk_pixbuf_new_from_file(DEFAULT_PROGRAM_ICON, NULL);
  }

  icon_pixbuf = gdk_pixbuf_scale_simple(temp_icon_pixbuf,
                                        CELL_ICON_SIZE,
                                        CELL_ICON_SIZE,
                                        GDK_INTERP_HYPER);
  mark = strrchr(path, '/');
  mark ++;
  gtk_list_store_append(list_store, &iter);
  gtk_list_store_set(list_store, &iter, ICON, icon_pixbuf, NAME,
                     mark, PATH, path, ALLOW, allow, -1);

  return;
}
static GtkListStore *get_list_store(void)
{
  GtkListStore *list_store = NULL;
  list_store = gtk_list_store_new(4,
                                  GDK_TYPE_PIXBUF,
                                  G_TYPE_STRING,
                                  G_TYPE_STRING,
                                  G_TYPE_BOOLEAN);
  return list_store;
}
static GtkWidget *get_tree_view(GtkListStore *list_store)
{
  GtkWidget *tree_view = NULL;
  GtkTreeViewColumn *column = NULL;
  GtkCellRenderer *cell_renderer = NULL;

  tree_view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(list_store));
  selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view));

  /*name*/
  column = gtk_tree_view_column_new();
  gtk_tree_view_column_set_title(column, TEXT_COLUMN_NAME);
  gtk_tree_view_column_set_resizable(column, TRUE);
  gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
  gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), column);

  //icon
  cell_renderer = gtk_cell_renderer_pixbuf_new();
  gtk_tree_view_column_pack_start(column, cell_renderer, TRUE);
  gtk_tree_view_column_set_attributes(column, cell_renderer, "pixbuf", ICON, NULL);
  //name
  cell_renderer = gtk_cell_renderer_text_new();
  gtk_tree_view_column_pack_start(column, cell_renderer, TRUE);
  gtk_tree_view_column_set_attributes(column, cell_renderer, "text", NAME, NULL);

  /*path*/
  column = gtk_tree_view_column_new();
  gtk_tree_view_column_set_title(column, TEXT_COLUMN_PATH);
  gtk_tree_view_column_set_resizable(column, TRUE);
  gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
  gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), column);
  cell_renderer = gtk_cell_renderer_text_new();
  gtk_tree_view_column_pack_start(column, cell_renderer, TRUE);
  gtk_tree_view_column_set_attributes(column, cell_renderer, "text", PATH, NULL);

  /*allow checkbox*/
  column = gtk_tree_view_column_new();
  gtk_tree_view_column_set_title(column, TEXT_NETWORK_ACCESS);
  gtk_tree_view_column_set_resizable(column, TRUE);
  gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
  gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), column);
  cell_renderer = gtk_cell_renderer_toggle_new();
  gtk_tree_view_column_pack_start(column, cell_renderer, TRUE);
  gtk_tree_view_column_set_attributes(column, cell_renderer, "active", ALLOW, NULL);
  gtk_signal_connect(GTK_OBJECT(cell_renderer), "toggled",
                     GTK_SIGNAL_FUNC(cellrender_toggled), NULL);

  return tree_view;
}
static void cellrender_toggled(GtkCellRendererToggle *cell_renderer,
                               gchar *path,
                               gpointer user_data)
{
  GtkTreeIter iter;
  gboolean status = 0;
  GValue value;
  char *program_path = NULL;
  value.g_type = G_TYPE_BOOLEAN;
  gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(list_store), &iter, path);
  gtk_tree_model_get(GTK_TREE_MODEL(list_store), &iter, PATH, &program_path, 
                     ALLOW, &status, -1);
  if (0 == status)
  {
    /*select the checkbutton*/
    value.data[0].v_int = 1;
    gtk_list_store_set_value(list_store, &iter, ALLOW, &value);
    /*modify app xml prop*/
    xml_allow_program((xmlChar *)program_path);
  }
  else
  {
    value.data[0].v_int = 0;
    gtk_list_store_set_value(list_store, &iter, ALLOW, &value);
    xml_deny_program((xmlChar *)program_path);
    del_process_cache_entry(program_path);
  }
  if (program_path != NULL)
  {
    free(program_path);
  }
}
static void init_program_list_store(GtkListStore *list_store)
{
  struct list_head *head = NULL;
  struct program_item *item = NULL;
  struct list_head *p = NULL;
  char *mark = NULL;
  GtkTreeIter iter;
  GdkPixbuf *temp_icon_pixbuf = NULL;
  GdkPixbuf *icon_pixbuf = NULL;
  char icon_path[256] = {0};

  char md5sum_now[MD5SUM_LEN+1]={0};

  head = get_program_list();

  list_for_each(p, head)
  {
    item = list_entry(p, struct program_item, list);
    md_buffer((void *)item->path, strlen(item->path), md5sum_now);
    sprintf(icon_path, "%s/%s.png", APP_ICON_PATH, md5sum_now);
    temp_icon_pixbuf = gdk_pixbuf_new_from_file(icon_path, NULL);
    if (NULL == temp_icon_pixbuf)
    {
      temp_icon_pixbuf = gdk_pixbuf_new_from_file(DEFAULT_PROGRAM_ICON, NULL);
    }

    icon_pixbuf = gdk_pixbuf_scale_simple(temp_icon_pixbuf,
                                          CELL_ICON_SIZE,
                                          CELL_ICON_SIZE,
                                          GDK_INTERP_HYPER);

    mark = strrchr(item->path, '/');
    mark ++;
    gtk_list_store_append(list_store, &iter);
    gtk_list_store_set(list_store, &iter, ICON, icon_pixbuf,
                       NAME, mark, PATH, item->path, ALLOW, item->allow, -1);

    memset(icon_path, 0,  sizeof(md5sum_now));
    mark = NULL;
  }

  free_program_list(p);
}
static void delete_item(GtkWidget *widget, gpointer data)
{
  GtkTreeIter iter;
  char *path = NULL;
  GtkTreeModel *model = GTK_TREE_MODEL(list_store);
  gboolean is_selected = FALSE;

  is_selected = gtk_tree_selection_get_selected(selection, &model, &iter);

  if (FALSE == is_selected)
  {
    return;
  }

  gtk_tree_model_get(GTK_TREE_MODEL(list_store), &iter, PATH, &path, -1);
  gtk_list_store_remove(list_store, &iter);
  xml_del_program_item((xmlChar *)path);
  del_process_cache_entry(path);

  if (path != NULL)
  {
    free(path);
  }
}
